package org.dreamwork.tools.io;

import org.dreamwork.tools.LogFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by seth.yang on 2018/12/11
 */
public class UpdateStub {
    public static final String KEY_STUB_PORT = "org.dreamwork.update-service.stub.port";
    private static final Logger logger = LogFactory.getLogger (UpdateStub.class);

    private static int port;

    static {
        String s_port = System.getProperty (KEY_STUB_PORT);
        if (s_port != null) {
            s_port = s_port.trim ();
            try {
                port = Integer.parseInt (s_port);
            } catch (Exception ex) {
                logger.log (Level.SEVERE, ex.getMessage ());
                throw new RuntimeException (ex);
            }
        }
    }

    public static void exit () throws IOException {
        try (Socket socket = new Socket ("127.0.0.1", port)) {
            socket.getOutputStream ().write (0);
            socket.getOutputStream ().flush ();
        }
    }

    public static void closeSplash () throws IOException {
        try (Socket socket = new Socket ("127.0.0.1", port)) {
            socket.getOutputStream ().write (2);
            socket.getOutputStream ().flush ();
        }
    }

    public static String checkUpdate (String category, String version, String url) throws IOException {
        try (Socket socket = new Socket ("127.0.0.1", port)) {
            DataOutputStream dos = new DataOutputStream (socket.getOutputStream ());
            dos.write (3);      // action, 3 for check update
            dos.writeUTF (category);
            dos.writeUTF (version);
            dos.writeUTF (url);

            socket.getOutputStream ().flush ();

            DataInputStream dis = new DataInputStream (socket.getInputStream ());
            int result = dis.readUnsignedByte ();
            if (result > 0) {
                return dis.readUTF ();
            }
            return null;
        }
    }

    public static void update (int type, String base) throws IOException {
        try (Socket socket = new Socket ("127.0.0.1", port)) {
            DataOutputStream dos = new DataOutputStream (socket.getOutputStream ());
            dos.write (1);      // action, 1 for update
            dos.write (type);   // the ui type
            dos.writeUTF (base);

            socket.getOutputStream ().flush ();
        }
    }

    public static UpdateMessage getScripts () throws IOException {
        try (Socket socket = new Socket ("127.0.0.1", port)) {
            socket.getOutputStream ().write (4);
            socket.getOutputStream ().flush ();

            DataInputStream dis = new DataInputStream (socket.getInputStream ());
            int count = dis.readUnsignedByte ();
            if (count > 0) {
                UpdateMessage message = new UpdateMessage ();
                message.version = dis.readUTF ();
//                List<Script> list = new ArrayList<> (count);
                message.scripts = new Script[count];
                for (int i = 0; i < count;  i ++) {
                    Script script   = new Script ();
                    script.type     = dis.readUTF ();
                    script.name     = dis.readUTF ();
                    script.location = dis.readUTF ();
                    message.scripts [i] = script;
//                    list.add (script);
                }

                return message;
            }
        }

        return null;
    }

    public static void clearScripts () throws IOException {
        try (Socket socket = new Socket ("127.0.0.1", port)) {
            socket.getOutputStream ().write (5);
            socket.getOutputStream ().flush ();
        }
    }

    public static final class UpdateMessage {
        public String version;
        public Script[] scripts;
    }

    public static final class Script {
        public String type;
        public String location;
        public String name;
    }
}